//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2008-2010, Shane J. M. Liesegang
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without 
// modification, are permitted provided that the following conditions are met:
// 
//     * Redistributions of source code must retain the above copyright 
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright 
//       notice, this list of conditions and the following disclaimer in the 
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of the copyright holder nor the names of any 
//       contributors may be used to endorse or promote products derived from 
//       this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
// POSSIBILITY OF SUCH DAMAGE.
//////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "DemoScreenPhysicsActor.h"
#include <cstdlib> 
#include <string>
#include <iostream>

#define CHAMELEON_TRANSPARENCY .75f
#define MOVEMENT_SPEED 7
#define EARTH_FRICTION .7f
#define PLATFORM_FRICTION EARTH_FRICTION
#define LEG_STRENGTH 18

using namespace std;

DemoScreenPhysicsActor::DemoScreenPhysicsActor()
{
}

void DemoScreenPhysicsActor::Start()
{
	//GenerateMaze();
	
	theWorld.LoadLevel("maze1");
	theWorld.NameLayer("background", 0);
	theWorld.NameLayer("foreground", 1);

	theWorld.LoadLevel("maze");
	mChameleon = new PhysicsActor();
	//PhysicsActors have all the same attributes as regular ones...
	mChameleon->SetSize(1.5f);
	mChameleon->SetColor(.63f, .63f, .63f);

	//...but with a little bit of magic pixie dust
	mChameleon->SetDensity(1.0f);
	mChameleon->SetFriction(.6f); //if both ground and character are max friction, slowness will ensue
	mChameleon->SetRestitution(0.0f); //bouncyness
	mChameleon->SetShapeType(PhysicsActor::SHAPETYPE_BOX);
	mChameleon->SetSprite("Resources/Images/trollface.png"); //Loads any image supported by DevIL (see docs)
	mChameleon->SetFixedRotation(1);
	mChameleon->SetLayer("foreground");
	mChameleon->InitPhysics();

	demoBg = new Actor();
	demoBg->SetSize(26, 20);
	demoBg->SetColor(1,1,1);
	demoBg->SetSprite("Resources/Images/backdemo.jpg");
	demoBg->SetLayer("background");

	theSwitchboard.SubscribeTo(this, "Jump");



	//That's the basics of what we've exposed from Box2d. There's lots
	//  more to it, though, and we encourage you to check out their
	//  documentation. http://box2d.org

	//and Din, with her strong arms, created the red (green) earth...
	/*p2 = new PhysicsActor();
	p2->SetPosition(0.0f, -11.0f);
	p2->SetSize(30.0f, 5.0f);
	p2->SetColor(0.0f, 1.0f, 0.0f);
	p2->SetDensity(0.0f); //no density (static)
	p2->SetFriction(EARTH_FRICTION); //little friction
	p2->InitPhysics(); */

	//NOTE: After you call InitPhysics, you can't directly set an Actor's
	// position or rotation -- you've turned those over to the physics engine.
	// You can't change the size, either, since that would mess up the simulation.

	theWorld.Add(mChameleon);
	//theWorld.Add(p2);
	theWorld.Add(demoBg);

    theSwitchboard.SubscribeTo(this, "CollisionWith" + mChameleon->GetName());
	
	//theWorld.Add(p2);

	//Demo housekeeping below this point. 
	#pragma region Demo Housekeeping
	_objects.push_back(mChameleon);
	//_objects.push_back(p2);
	ActorSet walls = theTagList.GetObjectsTagged("maze_wall");
	ActorSet::iterator it = walls.begin();
	while (it != walls.end())
	{
		int rando = rand()%14 + 1;
		string prefix("Resources/Images/tiles/block");
		char blockNum[3];
		itoa (rando,blockNum, 10);
		string spriteName = prefix + blockNum + ".png";
		(*it)->SetSprite(spriteName);
		theSwitchboard.SubscribeTo(this, "CollisionWith" + (*it)->GetName());
		_objects.push_back(*it);
		it++;
	}
	#pragma endregion
}

void DemoScreenPhysicsActor::Update(float dt)
{

	jumpPoint = mChameleon->GetPosition();
	
	/*if ((theController.IsConnected() && theController.IsBButtonDown()) || (theInput.OnKeyDown(GLFW_KEY_SPACE)))
	{
		//punch it upwards
		//mChameleon->ApplyImpulse(Vector2(0, LEG_STRENGTH), Vector2());
//mChameleon->ApplyForce(Vector2(0, 8), jumpPoint);
		
	}*/

	if((theInput.IsKeyDown('d')))
	{
		//move right
		mChameleon ->ApplyForce(Vector2(MOVEMENT_SPEED, 0), Vector2());
	}

	if((theInput.IsKeyDown('a')))
	{
		//move left
		mChameleon ->ApplyForce(Vector2(-MOVEMENT_SPEED, 0), Vector2());
	}

	//Color changing junks
	if((theInput.IsKeyDown(GLFW_KEY_UP) && !theInput.IsKeyDown(GLFW_KEY_DOWN) && !theInput.IsKeyDown(GLFW_KEY_LEFT) &&
		!theInput.IsKeyDown(GLFW_KEY_RIGHT)))
	{
		//Change color to Violet
		mChameleon ->SetColor(.5f, 0.0f, 1.0f, CHAMELEON_TRANSPARENCY); //R, G, B, A (there is also a Color class you can use)
		//mChameleon->ClearSpriteInfo(); //removes any texture that might have been assigned
	}	

	if((theInput.IsKeyDown(GLFW_KEY_UP) && !theInput.IsKeyDown(GLFW_KEY_DOWN) && !theInput.IsKeyDown(GLFW_KEY_LEFT) &&
		theInput.IsKeyDown(GLFW_KEY_RIGHT)))
	{
		//Change color to Pink
		mChameleon ->SetColor(1.0f, 0.0f, 1.0f, CHAMELEON_TRANSPARENCY); //R, G, B, A (there is also a Color class you can use)
		//mChameleon->ClearSpriteInfo(); //removes any texture that might have been assigned
	}

	if((!theInput.IsKeyDown(GLFW_KEY_UP) && !theInput.IsKeyDown(GLFW_KEY_DOWN) && !theInput.IsKeyDown(GLFW_KEY_LEFT) &&
		theInput.IsKeyDown(GLFW_KEY_RIGHT)))
	{
		//Change color to Red
		mChameleon ->SetColor(1.0f, 0.0f, 0.0f, CHAMELEON_TRANSPARENCY); //R, G, B, A (there is also a Color class you can use)
		//mChameleon->ClearSpriteInfo(); //removes any texture that might have been assigned
	}

	if((!theInput.IsKeyDown(GLFW_KEY_UP) && theInput.IsKeyDown(GLFW_KEY_DOWN) && !theInput.IsKeyDown(GLFW_KEY_LEFT) &&
		theInput.IsKeyDown(GLFW_KEY_RIGHT)))
	{
		//Change color to Orange
		mChameleon ->SetColor(1.0f, 0.5f, 0.0f, CHAMELEON_TRANSPARENCY); //R, G, B, A (there is also a Color class you can use)
		//mChameleon->ClearSpriteInfo(); //removes any texture that might have been assigned
	}

	if((!theInput.IsKeyDown(GLFW_KEY_UP) && theInput.IsKeyDown(GLFW_KEY_DOWN) && !theInput.IsKeyDown(GLFW_KEY_LEFT) &&
		!theInput.IsKeyDown(GLFW_KEY_RIGHT)))
	{
		//Change color to Yellow
		mChameleon ->SetColor(1.0f, 1.0f, 0.0f, CHAMELEON_TRANSPARENCY); //R, G, B, A (there is also a Color class you can use)
		//mChameleon->ClearSpriteInfo(); //removes any texture that might have been assigned
	}

	if((!theInput.IsKeyDown(GLFW_KEY_UP) && theInput.IsKeyDown(GLFW_KEY_DOWN) && theInput.IsKeyDown(GLFW_KEY_LEFT) &&
		!theInput.IsKeyDown(GLFW_KEY_RIGHT)))
	{
		//Change color to Green
		mChameleon ->SetColor(0.0f, 1.0f, 0.0f, CHAMELEON_TRANSPARENCY); //R, G, B, A (there is also a Color class you can use)
		//mChameleon->ClearSpriteInfo(); //removes any texture that might have been assigned
	}

	if((!theInput.IsKeyDown(GLFW_KEY_UP) && !theInput.IsKeyDown(GLFW_KEY_DOWN) && theInput.IsKeyDown(GLFW_KEY_LEFT) &&
		!theInput.IsKeyDown(GLFW_KEY_RIGHT)))
	{
		//Change color to Cyan
		mChameleon ->SetColor(0.0f, 1.0f, 1.0f, CHAMELEON_TRANSPARENCY); //R, G, B, A (there is also a Color class you can use)
		//mChameleon->ClearSpriteInfo(); //removes any texture that might have been assigned
	}

	if((theInput.IsKeyDown(GLFW_KEY_UP) && !theInput.IsKeyDown(GLFW_KEY_DOWN) && theInput.IsKeyDown(GLFW_KEY_LEFT) &&
		!theInput.IsKeyDown(GLFW_KEY_RIGHT)))
	{
		//Change color to Blue
		mChameleon ->SetColor(0.0f, 0.0f, 1.0f, CHAMELEON_TRANSPARENCY); //R, G, B, A (there is also a Color class you can use)
		///mChameleon->ClearSpriteInfo(); //removes any texture that might have been assigned
	}

	if((!theInput.IsKeyDown(GLFW_KEY_UP) && !theInput.IsKeyDown(GLFW_KEY_DOWN) && !theInput.IsKeyDown(GLFW_KEY_LEFT) &&
		!theInput.IsKeyDown(GLFW_KEY_RIGHT)))
	{
		//Change color to Default
		mChameleon ->SetColor(.63f, 0.63f, 0.63f, 1); //R, G, B, A (there is also a Color class you can use)
		//mChameleon->ClearSpriteInfo(); //removes any texture that might have been assigned
	}

	//mChameleon->GetBody()->

}

void DemoScreenPhysicsActor::ReceiveMessage(Message *message)
{
	//Respond to the ScreenStarted message that we sent when the screen started. 
	if (message->GetMessageName() == "Jump")
	{
		if(mChameleon->GetBody()->GetLinearVelocity().y == 0)
		{
			mChameleon->ApplyImpulse(Vector2(0, LEG_STRENGTH), jumpPoint);
		}
	}
	else if (message->GetMessageName() == "CollisionWith" + mChameleon->GetName())
	{
		cout << "mChameleon Name: " +  mChameleon->GetName() << endl;
	}
else if (message->GetMessageName().find("Wall", 0))
{
	cout << "Bingo " + message->GetMessageName() << endl;
}
	else
	{
		cout << "Message unhandled " + message->GetMessageName() << endl;
	}


}

void DemoScreenPhysicsActor::GenerateMaze()
{
	double leftWall = -13.0;
	double rightWall = 13.0;
	double topWall = 9.6;
	double bottomWall = -9.6;
	double xSize = 1; //x size of each tile
	double ySize = 1; //y size of each tile
}
